package com.d3works.apps.account.web;

import com.d3works.apps.account.db.AccountingSituation;
import com.d3works.apps.account.db.repo.AccountConfigRepository;
import com.d3works.apps.account.db.repo.AccountTypeRepository;
import com.d3works.apps.account.db.repo.InvoiceRepository;
import com.d3works.apps.account.db.repo.MoveLineRepository;
import com.d3works.apps.account.db.repo.NotificationRepository;
import com.d3works.apps.account.service.AccountingSituationInitService;
import com.d3works.apps.account.service.PartnerAccountService;
import com.d3works.apps.base.db.Partner;
import com.d3works.apps.base.db.repo.PartnerRepository;
import com.d3works.exception.D3worksException;
import com.d3works.exception.service.TraceBackService;
import com.d3works.inject.Beans;
import com.d3works.rpc.ActionRequest;
import com.d3works.rpc.ActionResponse;
import com.google.inject.Singleton;
import java.util.List;

@Singleton
public class PartnerController {

  public void createAccountingSituations(ActionRequest request, ActionResponse response)
      throws D3worksException {

    Partner partner = request.getContext().asType(Partner.class);

    List<AccountingSituation> accountingSituationList =
        Beans.get(AccountingSituationInitService.class)
            .createAccountingSituation(Beans.get(PartnerRepository.class).find(partner.getId()));

    if (accountingSituationList != null) {
      response.setValue("accountingSituationList", accountingSituationList);
    }
  }

  public void getDefaultSpecificTaxNote(ActionRequest request, ActionResponse response) {

    Partner partner = request.getContext().asType(Partner.class);
    response.setValue(
        "specificTaxNote",
        Beans.get(PartnerAccountService.class).getDefaultSpecificTaxNote(partner));
  }

  public void checkAnyCompanyAccountConfigAttached(ActionRequest request, ActionResponse response) {
    try {
      Partner partner = request.getContext().asType(Partner.class);
      if (!partner.getIsFactor()) {
        long accountConfigCount =
            Beans.get(AccountConfigRepository.class)
                .all()
                .filter("self.factorPartner = :factorPartner")
                .bind("factorPartner", partner.getId())
                .count();
        if (accountConfigCount > 0) {
          response.setValue("factorCantBeRemoved", true);
        }
      }
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }

  public void checkAnyNotificationAttached(ActionRequest request, ActionResponse response) {
    try {
      Partner partner = request.getContext().asType(Partner.class);
      if (!partner.getIsFactor()) {
        long notificationCount =
            Beans.get(NotificationRepository.class)
                .all()
                .filter("self.factorPartner = :factorPartner")
                .bind("factorPartner", partner.getId())
                .count();
        if (notificationCount > 0) {
          response.setValue("factorCantBeRemoved", true);
        }
      }
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }

  public void checkAnyPayableMoveLineAttached(ActionRequest request, ActionResponse response) {
    try {
      Partner partner = request.getContext().asType(Partner.class);
      if (!partner.getIsSupplier()) {
        long moveLineCount =
            Beans.get(MoveLineRepository.class)
                .all()
                .filter(
                    "self.partner = :partner AND self.account.accountType.technicalTypeSelect = :technicalTypeSelect")
                .bind("partner", partner.getId())
                .bind("technicalTypeSelect", AccountTypeRepository.TYPE_PAYABLE)
                .count();
        if (moveLineCount > 0) {
          response.setValue("supplierCantBeRemoved", true);
        }
      }
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }

  public void checkAnyInvoiceSupplierPurchaseAttached(
      ActionRequest request, ActionResponse response) {
    try {
      Partner partner = request.getContext().asType(Partner.class);
      if (!partner.getIsSupplier()) {
        long invoiceCount =
            Beans.get(InvoiceRepository.class)
                .all()
                .filter(
                    "self.operationTypeSelect = :operationTypeSelect AND self.partner = :partner")
                .bind("operationTypeSelect", InvoiceRepository.OPERATION_TYPE_SUPPLIER_PURCHASE)
                .bind("partner", partner.getId())
                .count();
        if (invoiceCount > 0) {
          response.setValue("supplierCantBeRemoved", true);
        }
      }
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }

  public void checkAnyReceivableMoveLineAttached(ActionRequest request, ActionResponse response) {
    try {
      Partner partner = request.getContext().asType(Partner.class);
      if (!partner.getIsCustomer()) {
        long moveLineCount =
            Beans.get(MoveLineRepository.class)
                .all()
                .filter(
                    "self.partner = :partner AND self.account.accountType.technicalTypeSelect = :technicalTypeSelect")
                .bind("partner", partner.getId())
                .bind("technicalTypeSelect", AccountTypeRepository.TYPE_RECEIVABLE)
                .count();
        if (moveLineCount > 0) {
          response.setValue("customerCantBeRemoved", true);
        }
      }
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }

  public void checkAnyInvoiceClientSaleAttached(ActionRequest request, ActionResponse response) {
    try {
      Partner partner = request.getContext().asType(Partner.class);
      if (!partner.getIsCustomer()) {
        long invoiceCount =
            Beans.get(InvoiceRepository.class)
                .all()
                .filter(
                    "self.operationTypeSelect = :operationTypeSelect AND self.partner = :partner")
                .bind("operationTypeSelect", InvoiceRepository.OPERATION_TYPE_CLIENT_SALE)
                .bind("partner", partner.getId())
                .count();
        if (invoiceCount > 0) {
          response.setValue("customerCantBeRemoved", true);
        }
      }
    } catch (Exception e) {
      TraceBackService.trace(response, e);
    }
  }
}
